/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

using VSTrid = Microsoft.VisualStudio.VirtualTreeGrid;

using DslEditorPowerToy.Controls.VirtualTreeGrid.Validation;

namespace DslEditorPowerToy.Controls.VirtualTreeGrid.Branches
{
    public abstract class BranchBase : VSTrid.IBranch, IDataItemBranch, VSTrid.IMultiColumnBranch
    {
        public const short NoDataItemImage = -1;
        private VirtualTreeGridControl _treeControl = null;
        private ColumnManager _columnManager = null;

        #region Constructors
        protected BranchBase(VirtualTreeGridControl treeControl, Type branchDataItemType)
        {
            ArgumentValidator.ValidateNotNull("treeControl", treeControl);
            ArgumentValidator.ValidateNotNull("branchDataItemType", branchDataItemType);

            this._treeControl = treeControl;
            this._columnManager = new ColumnManager(branchDataItemType);
        }
        #endregion

        #region Protected Properties
        /// <summary>
        /// Gets the underlying tree control
        /// </summary>
        protected VirtualTreeGridControl TreeControl
        {
            get
            {
                return this._treeControl;
            }
        }
        /// <summary>
        /// Gets if the branch allows additions to dataItem items
        /// </summary>
        protected virtual bool AllowAdds
        {
            get
            {
                return ((this.Features & VSTrid.BranchFeatures.InsertsAndDeletes) > 0);
            }
        }
        /// <summary>
        /// Gets if the branch allows removal of dataItem items
        /// </summary>
        protected virtual bool AllowDeletes
        {
            get
            {
                return ((this.Features & VSTrid.BranchFeatures.InsertsAndDeletes) > 0);
            }
        }
        /// <summary>
        /// Gets if the branch allows repositioning of dataItem items
        /// </summary>
        protected virtual bool AllowMoves
        {
            get
            {
                return (this.AllowAdds && this.AllowDeletes);
            }
        }
        /// <summary>
        /// Gets the image list to use for display items
        /// </summary>
        protected virtual ImageList DataItemImageList
        {
            get
            {
                return null;
            }
        }
        #endregion

        #region IBranch Members
        public event VSTrid.BranchModificationEventHandler OnBranchModification;
        /// <summary>
        /// Return the features supported by this navigationBranch.
        /// </summary>
        /// <value></value>
        public virtual VSTrid.BranchFeatures Features
        {
            get
            {
                VSTrid.BranchFeatures features = VSTrid.BranchFeatures.None;
                
                //Add state changes
                if (true == this.TreeControl.StandardCheckBoxes)
                    features |= VSTrid.BranchFeatures.StateChanges;

                return features;
            }
        }
        /// <summary>
        /// not called
        /// </summary>
        public int UpdateCounter
        {
            get
            {
                System.Diagnostics.Debug.Assert(false, "Should not be called here");
                return 0;
            }
        }

        #region Data Display
        /// <summary>
        /// Return the count of visible items in this navigationBranch.
        /// </summary>
        /// <value></value>
        public abstract int VisibleItemCount
        {
            get;
        }
        /// <summary>
        /// Returns the position of the specified object in the branch
        /// </summary>
        public virtual VSTrid.LocateObjectData LocateObject(object obj, VSTrid.ObjectStyle style, int locateOptions)
        {
            switch (style)
            {
                default:
                    return new VSTrid.LocateObjectData(-1, -1, (int)VSTrid.TrackingObjectAction.NotTracked);
            }
        }
        /// <summary>
        /// Returns the object at specified position and type
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="style"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public abstract object GetObject(int row, int column, VSTrid.ObjectStyle style, ref int options);
        /// <summary>
        /// Returns the text for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <returns></returns>
        public virtual string GetText(int row, int column)
        {
            return GetDataItemDisplayText(row, column);
        }
        /// <summary>
        /// Determines if specified item is expandable
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <returns></returns>
        public virtual bool IsExpandable(int row, int column)
        {
            return ((this.Features & VSTrid.BranchFeatures.Expansions) != 0);
        }
        /// <summary>
        /// Returns the accessibility dataItem for the control
        /// </summary>
        /// <param name="row"></param>
        /// <param name="col"></param>
        /// <returns></returns>
        public virtual VSTrid.VirtualTreeAccessibilityData GetAccessibilityData(int row, int col)
        {
            return new VSTrid.VirtualTreeAccessibilityData();
        }
        /// <summary>
        /// Returns the requested display information        
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="requiredData"></param>
        /// <returns></returns>
        public virtual VSTrid.VirtualTreeDisplayData GetDisplayData(int row, int column,
            VSTrid.VirtualTreeDisplayDataMasks requiredData)
        {
            VSTrid.VirtualTreeDisplayData data = VSTrid.VirtualTreeDisplayData.Empty;

            //Set image
            if ((requiredData.Mask & VSTrid.VirtualTreeDisplayMasks.Image) != 0)
            {
                //Get Image list from derived class
                ImageList images = this.DataItemImageList;
                if (null != images)
                {
                    //Get image index from derived class
                    short imageIndex = GetDataItemImageIndex(row, column);
                    if (imageIndex > NoDataItemImage)
                    {
                        data.ImageList = images;
                        data.Image = imageIndex;
                    }

                    if ((requiredData.Mask & VSTrid.VirtualTreeDisplayMasks.SelectedImage) != 0)
                    {
                        short selectedImageIndex = GetDataItemSelectedImageIndex(row, column);
                        if (selectedImageIndex > NoDataItemImage)
                        {
                            data.ImageList = images;
                            data.SelectedImage = selectedImageIndex;
                        }
                    }
                }
            }

            object dataItem = this.GetDataItem(row);
            if (null != dataItem)
            {
                ColumnDescriptor descriptor = this.GetDataItemDescriptorByColumn(dataItem, column);
                if (null != descriptor)
                {
                    //Set color of text based on descriptor status
                    if ((requiredData.Mask & VSTrid.VirtualTreeDisplayMasks.Color) != 0)
                        data.GrayText = descriptor.IsReadOnly;

                    //Set state image for boolean types (if supported)
                    if (true == this.TreeControl.StandardCheckBoxes)
                    {
                        if ((requiredData.Mask & VSTrid.VirtualTreeDisplayMasks.StateImage) != 0)
                        {
                            //Check if current descriptor is for a boolean property
                            if (descriptor.Converter is BooleanConverter)
                            {
                                bool value = Convert.ToBoolean(descriptor.GetValue(dataItem));
                                VSTrid.StandardCheckBoxImage imageIndex = VSTrid.StandardCheckBoxImage.Inactive;

                                if (true == value)
                                {
                                    imageIndex = (true == descriptor.IsReadOnly) ? VSTrid.StandardCheckBoxImage.CheckedDisabled :
                                        VSTrid.StandardCheckBoxImage.Checked;
                                }
                                else
                                {
                                    imageIndex = (true == descriptor.IsReadOnly) ? VSTrid.StandardCheckBoxImage.UncheckedDisabled :
                                        VSTrid.StandardCheckBoxImage.Unchecked;
                                }
                                data.StateImageIndex = (short)imageIndex;
                            }
                        }
                    }
                }
            }
            return data;
        }
        /// <summary>
        /// Returns the tip text for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="tipType"></param>
        /// <returns></returns>
        public virtual string GetTipText(int row, int column, VSTrid.ToolTipType tipType)
        {
            //Always return the textual value
            return null;
        }
        #endregion

        #region State Changes
        /// <summary>
        /// Handles state change for the specified cell, and returns what needs 
        /// to be refreshed if the state changes for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <returns></returns>
        public virtual VSTrid.StateRefreshChanges ToggleState(int row, int column)
        {
            //Check if supporting state changes
            if (true == this.TreeControl.StandardCheckBoxes)
            {
                object dataItem = this.GetDataItem(row);
                if (null != dataItem)
                {
                    ColumnDescriptor descriptor = this.GetDataItemDescriptorByColumn(dataItem, column);
                    if (null != descriptor)
                    {
                        //We only support the current item
                        if (descriptor.Converter is BooleanConverter)
                        {
                            bool value = Convert.ToBoolean(descriptor.GetValue(dataItem));
                            UpdateResult result = SetDataItemValue(row, column, (!value).ToString());
                            if (UpdateResult.Updated == result)
                                return VSTrid.StateRefreshChanges.Current;
                        }
                    }
                }
            }

            return VSTrid.StateRefreshChanges.None;
        }
        /// <summary>
        /// Handles a state change for the specified cell, (as part of a multiple selection group)
        /// and returns what else needs to be refreshed if the state changes for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="navigationBranch"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public virtual VSTrid.StateRefreshChanges SynchronizeState(int row, int column, VSTrid.IBranch branch, int x, int y)
        {
            //We currently dont support toggling state of multiple items
            return VSTrid.StateRefreshChanges.None;
        }
        #endregion

        #region Label Editing
        /// <summary>
        /// Returns the action to take when starting label editing
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="activationStyle"></param>
        /// <returns></returns>
        public virtual VSTrid.VirtualTreeLabelEditData BeginLabelEdit(int row, int column,
            VSTrid.VirtualTreeLabelEditActivationStyles activationStyle)
        {
            //We dont allow immediate activation because we may have controls 
            //that don't correctly handle navigation keys
            if (VSTrid.VirtualTreeLabelEditActivationStyles.ImmediateSelection == activationStyle)
                return VSTrid.VirtualTreeLabelEditData.DeferActivation;

            //Get the underlying data item
            object dataItem = GetDataItem(row);
            if (null == dataItem)
                return VSTrid.VirtualTreeLabelEditData.Invalid;

            VSTrid.VirtualTreeLabelEditData editData = VSTrid.VirtualTreeLabelEditData.Default;
            ColumnDescriptor descriptor = this.GetDataItemDescriptorByColumn(dataItem, column);
            if (null == descriptor)
                return VSTrid.VirtualTreeLabelEditData.Invalid;
            else
            {
                //Ensure editable property
                if (true == descriptor.IsReadOnly)
                    return VSTrid.VirtualTreeLabelEditData.Invalid;

                //Check if using state images
                if (true == this.TreeControl.StandardCheckBoxes)
                {
                    if (descriptor.Converter is BooleanConverter)
                        return VSTrid.VirtualTreeLabelEditData.Invalid;
                }

                //Check if any custom editor
                VSTrid.TypeEditorHost editor = descriptor.GetEditorHost(dataItem);
                if (null != editor)
                    editData.CustomInPlaceEdit = editor;
                else
                {
                    //Get the text value to actually edit (via propertyDescriptor)
                    //(Uses default text editor)
                    editData.AlternateText = descriptor.GetValue(dataItem).ToString();
                }
            }

            return editData;
        }
        /// <summary>
        /// Returns the action to take after label editing complete
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public virtual VSTrid.LabelEditResult CommitLabelEdit(int row, int column, string newText)
        {
            UpdateResult result = SetDataItemValue(row, column, newText);
            switch (result)
            {
                case UpdateResult.Ignored:
                    return VSTrid.LabelEditResult.CancelEdit;

                case UpdateResult.InvalidValue:
                    return VSTrid.LabelEditResult.BlockDeactivate;

                case UpdateResult.Updated:
                    return VSTrid.LabelEditResult.AcceptEdit;

                default:
                    return VSTrid.LabelEditResult.CancelEdit;
            }
        }
        #endregion

        #region Drag and Drop
        public virtual VSTrid.VirtualTreeStartDragData OnStartDrag(object sender, int row, int column, VSTrid.DragReason reason)
        {
            //We dont support drag & drop
            return VSTrid.VirtualTreeStartDragData.Empty;
        }
        public virtual void OnDragEvent(object sender, int row, int column, VSTrid.DragEventType eventType, DragEventArgs args)
        {
            //we dont support drag & drop
        }
        public virtual void OnGiveFeedback(GiveFeedbackEventArgs args, int x, int y)
        {
            //we dont support drag & drop
        }
        public virtual void OnQueryContinueDrag(QueryContinueDragEventArgs args, int x, int y)
        {
            //we dont support drag & drop
        }
        #endregion

        #endregion

        #region IDataItemBranch
        /// <summary>
        /// Returns the data for the row
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public abstract object GetDataItem(int row);
        /// <summary>
        /// Returns the name of the column at specified index
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        public virtual string GetDataItemPropertyName(int column)
        {
            return this._columnManager.GetDescriptorNameByColumn(column);
        }
        /// <summary>
        /// Returns the value of the cell at specified row and column
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        public virtual object GetDataItemPropertyValue(int row, int column)
        {
            return GetDataItemValue(row, column);
        }
        /// <summary>
        /// Returns the validation error for the specified property and value
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public virtual string GetDataItemValidationMessage(string propertyName, string value)
        {
            return string.Empty;
        }
        /// <summary>
        /// Removes item from branch dataItem
        /// </summary>
        /// <param name="row"></param>
        public virtual bool RemoveDataItem(int row)
        {
            return this.AllowDeletes;
        }
        /// <summary>
        /// Changes order of branch dataItem
        /// </summary>
        /// <param name="fromRow"></param>
        /// <param name="toRow"></param>
        public virtual bool MoveDataItem(int fromRow, int toRow)
        {
            return (this.AllowMoves);
        }
        /// <summary>
        /// Returns the flags for the current dataItem item
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public virtual DataItemFlags GetDataItemFlags(int row)
        {
            if (row < 0)
                return DataItemFlags.None;
            else
            {
                DataItemFlags flags = DataItemFlags.None;
                if (true == this.AllowDeletes)
                    flags |= DataItemFlags.CanDelete;
                if (true == this.AllowMoves)
                    flags |= DataItemFlags.CanMove;
                return flags;
            }
        }
        /// <summary>
        /// Updates the text of column headers for current row values
        /// </summary>
        /// <param name="row"></param>
        public virtual void OnDataItemSelectionChanged(int row)
        {
            //Get the data item for this row
            object dataItem = this.GetDataItem(row);
            if (null == dataItem)
                return;

            //Update all the column headers
            int branchColumnCount = this.ColumnCount;
            for (int columnIndex = 0; columnIndex < branchColumnCount; columnIndex++)
                UpdateColumnHeader(columnIndex, dataItem);

            //Blank other columns
            int treeControlColumnCount = this.TreeControl.Columns.Count;
            for (int columnIndex = branchColumnCount; columnIndex < treeControlColumnCount; columnIndex++)
                UpdateColumnHeader(columnIndex, @" ");
        }
        #endregion

        #region IMultiColumnBranch Members
        /// <summary>
        /// Returns the number of columns to display
        /// That is, the columns with data to be displayed
        /// </summary>
        public virtual int ColumnCount
        {
            get
            {
                int visibleColumns = this.TreeControl.Columns.Count;
                int branchColumns = this._columnManager.GetColumnCount(this);
                return System.Math.Min(visibleColumns, branchColumns);
            }
        }
        public virtual VSTrid.SubItemCellStyles ColumnStyles(int column)
        {
            return VSTrid.SubItemCellStyles.Simple;
        }
        /// <summary>
        /// Returns number of jagged columns
        /// That is, the number of physical columns shown from left
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public virtual int GetJaggedColumnCount(int row)
        {
            return this.ColumnCount;
        }

        #endregion

        #region Protected Methods
        /// <summary>
        /// Returns the index of the image within the DataItemImageList for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        protected virtual short GetDataItemImageIndex(int row, int column)
        {
            return NoDataItemImage;
        }
        /// <summary>
        /// Returns the index of the selected image within the DataItemImageList for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        protected virtual short GetDataItemSelectedImageIndex(int row, int column)
        {
            return GetDataItemImageIndex(row, column);
        }
        /// <summary>
        /// Return the value of the specified cell
        /// </summary>
        /// <param name="column"></param>
        /// <param name="dataItem"></param>
        protected string GetDataItemValue(int row, int column)
        {
            object dataItem = GetDataItem(row);
            if (null == dataItem)
                return null;

            ColumnDescriptor descriptor = this.GetDataItemDescriptorByColumn(dataItem, column);
            if (null == descriptor)
                return null;
            else
                return descriptor.GetValue(dataItem).ToString();
        }
        /// <summary>
        /// Return the textual value of the specified cell
        /// </summary>
        /// <param name="column"></param>
        /// <param name="dataItem"></param>
        protected string GetDataItemDisplayText(int row, int column)
        {
            //Check if using state images
            if (true == this.TreeControl.StandardCheckBoxes)
            {
                object dataItem = GetDataItem(row);
                if (null == dataItem)
                    return null;

                ColumnDescriptor descriptor = this.GetDataItemDescriptorByColumn(dataItem, column);
                if (null == descriptor)
                    return null;

                if (descriptor.Converter is BooleanConverter)
                    return null;
            }

            return GetDataItemValue(row, column);
        }
        /// <summary>
        /// Returns the runtime propertyDescriptor for the dataItem for the the specified column
        /// </summary>
        /// <param name="dataItem"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        protected ColumnDescriptor GetDataItemDescriptorByColumn(object dataItem, int column)
        {
            return this._columnManager.GetDescriptorByColumn(dataItem, column);
        }
        /// <summary>
        /// Updates the value of the dataItem item's property, and returns the success.
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <param name="value"></param>
        /// <param name="dataItem"></param>
        /// <returns></returns>
        protected UpdateResult SetDataItemValue(int row, int column, string value)
        {
            object dataItem = GetDataItem(row);
            if (null == dataItem)
                return UpdateResult.Ignored;

            ColumnDescriptor propertyDescriptor = this.GetDataItemDescriptorByColumn(dataItem, column);
            if (null == propertyDescriptor)
                return UpdateResult.Ignored;
            else
            {
                //Ensure editable property
                if (true == propertyDescriptor.IsReadOnly)
                    return UpdateResult.Ignored;

                //Validate value (pre-step to ensure is valid)
                if (false == propertyDescriptor.IsValid(value))
                {
                    //Get validation error
                    string validationMessage = GetDataItemValidationMessage(propertyDescriptor.Name, value);
                    if (true == string.IsNullOrEmpty(validationMessage))
                        ValidationHelper.DisplayDefaultValidationError();
                    else
                        ValidationHelper.DisplayError(validationMessage);
                    return UpdateResult.InvalidValue;
                }
                else
                {
                    //Set value (via propertyDescriptor)
                    propertyDescriptor.SetValue(dataItem, value);

                    //Raise changed event
                    this.OnBranchDataItemChanged(
                        new VSTrid.DisplayDataChangedData(VSTrid.VirtualTreeDisplayDataChanges.Text,
                        this, row, column, 1));
                    return UpdateResult.Updated;
                }
            }
        }

        #region Event Raising Helpers
        /// <summary>
		/// Raises branch modification event
		/// </summary>
        protected void OnBranchModified(VSTrid.BranchModificationEventArgs modification)
		{
			if (null != this.OnBranchModification)
				OnBranchModification(this, modification);
        }
        /// <summary>
        /// Raises the branch item added event
        /// </summary>
        /// <param name="row">The row after which the item was added</param>
        protected void OnBranchDataItemAdded(int row)
        {
            OnBranchModified(VSTrid.BranchModificationEventArgs.InsertItems(this, (row - 1), 1));
        }
        /// <summary>
        /// Raises the branch item removed event
        /// </summary>
        /// <param name="row">The row which was deleted</param>
        protected void OnBranchDataItemRemoved(int row)
        {
            OnBranchModified(VSTrid.BranchModificationEventArgs.DeleteItems(this, row, 1));
        }
        /// <summary>
        /// Raises the branch item moved event
        /// </summary>
        protected void OnBranchDataItemMoved(int fromRow, int toRow)
        {
            OnBranchModified(VSTrid.BranchModificationEventArgs.MoveItem(this, fromRow, toRow));
        }
        /// <summary>
        /// Raises the branch dataItem changed event
        /// </summary>
        /// <param name="changeData"></param>
        protected void OnBranchDataItemChanged(VSTrid.DisplayDataChangedData changeData)
        {
            OnBranchModified(VSTrid.BranchModificationEventArgs.DisplayDataChanged(changeData));
        }
        /// <summary>
        /// Raises the branch dataItem changed event
        /// </summary>
        /// <param name="changeData"></param>
        protected void OnBranchDataItemChanged(int row)
        {
            Microsoft.VisualStudio.VirtualTreeGrid.DisplayDataChangedData changes = 
                new Microsoft.VisualStudio.VirtualTreeGrid.DisplayDataChangedData( Microsoft.VisualStudio.VirtualTreeGrid.VirtualTreeDisplayDataChanges.All, this, row, 0, 1);

            OnBranchModified(VSTrid.BranchModificationEventArgs.DisplayDataChanged(changes));
        }        
        /// <summary>
        /// Raises the branch dataItem changed event for all items in branch
        /// </summary>
        /// <param name="changeData"></param>
        protected void OnBranchDataItemChanged(Microsoft.VisualStudio.VirtualTreeGrid.VirtualTreeDisplayDataChanges change)
        {
            int rowCount = this.VisibleItemCount;
            Microsoft.VisualStudio.VirtualTreeGrid.DisplayDataChangedData changes =
                new Microsoft.VisualStudio.VirtualTreeGrid.DisplayDataChangedData(change, this, 0, 0, rowCount);

            OnBranchModified(VSTrid.BranchModificationEventArgs.DisplayDataChanged(changes));
        }           
        #endregion

        #endregion

        #region Private Methods
        /// <summary>
        /// Updates column header to reflect the data item
        /// </summary>
        /// <param name="branchColumnIndex"></param>
        /// <param name="descriptor"></param>
        private void UpdateColumnHeader(int column, object dataItem)
        {
            //Get current descriptor
            ColumnDescriptor descriptor = this._columnManager.GetDescriptorByColumn(dataItem, column);
            if (null == descriptor)
                return;

            //Update header text
            VSTrid.VirtualTreeColumnHeader header = this.TreeControl.Columns[column];
            if (null != header)
            {
                string headerText = (string.IsNullOrEmpty(descriptor.DisplayName)) ? descriptor.Name : descriptor.DisplayName;
                this.TreeControl.UpdateColumnHeaderAppearance(column, headerText, header.Style, header.ImageIndex);
            }
        }
        /// <summary>
        /// Updates column header with text
        /// </summary>
        /// <param name="branchColumnIndex"></param>
        /// <param name="descriptor"></param>
        private void UpdateColumnHeader(int column, string headerText)
        {
            //Update header text
            VSTrid.VirtualTreeColumnHeader header = this.TreeControl.Columns[column];
            if (null != header)
                this.TreeControl.UpdateColumnHeaderAppearance(column, headerText, header.Style, header.ImageIndex);
        }
        #endregion

        #region Enumerations
        protected enum UpdateResult
        {
            Updated,
            InvalidValue,
            Ignored
        }
        #endregion
    }
}
